package org.jmc.refmanager.web.wicket.page.service;

import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import org.apache.wicket.PageParameters;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.authorization.strategies.role.annotations.AuthorizeInstantiation;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow.MaskType;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.RequiredTextField;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.apache.wicket.validation.validator.PatternValidator;
import org.jmc.refmanager.domain.model.OrgUnit;
import org.jmc.refmanager.domain.model.User;
import org.jmc.refmanager.domain.service.ChangeManager;
import org.jmc.refmanager.domain.service.OrgUnitManager;
import org.jmc.refmanager.domain.service.UserManager;
import org.jmc.refmanager.domain.service.exception.BusinessException;
import org.jmc.refmanager.security.SecurityHelper;
import org.jmc.refmanager.util.Util;
import org.jmc.refmanager.web.wicket.form.ServiceNewForm;
import org.jmc.refmanager.web.wicket.page.panel.SelectCodePostalPanel2;
import org.jmc.refmanager.web.wicket.page.panel.SelectParentPanel1;
import org.jmc.refmanager.web.wicket.page.search.ServicesListPage;
import org.jmc.refmanager.web.wicket.page.template.TemplatePage;

/**
 */
@AuthorizeInstantiation(value={"ROLE_MODIF", "ROLE_APPROVER"})
public class ServiceNewPage extends TemplatePage {
	@SpringBean(name="orgUnitManager")
	private OrgUnitManager orgUnitManager;

	@SpringBean(name="taskManager")
	private ChangeManager taskManager;
	
	@SpringBean(name="userManager")
	private UserManager userManager;

	/**
	 * @param parameters
	 */
	public ServiceNewPage(PageParameters parameters) {
		super(parameters);
		initComponents(parameters);
	}

	/*
	 * 
	 * @param parentId
	 * @return
	 */
	private OrgUnit createNewService(Integer parentId) {
		OrgUnit newService = new OrgUnit();
		newService.setCodeUO(Util.generateCodeUO());

		if (parentId != null) {
			OrgUnit parentService = orgUnitManager.findById(parentId);
			newService.setParent(parentService);
		}

		newService.setCree(true);
		newService.setSao(true);
		
		return newService;
	}
	
	/*
	 * 
	 * @param parameters
	 */
	private void initComponents(PageParameters parameters) {
		add(new Label("pageTitle", "Création de service"));

		final String matricule = SecurityHelper.getAuthentication().getName();
		
		Integer parentId = parameters.getAsInteger("parentId");
		OrgUnit newService = createNewService(parentId);

		final IModel<OrgUnit> serviceModel = new Model<OrgUnit>(newService);
				
		final RequiredTextField<String> codePostalTextField = new RequiredTextField<String>("codePostal", 
				new PropertyModel<String>(serviceModel, "codePostal"));
		codePostalTextField.setOutputMarkupId(true);
		codePostalTextField.add(new PatternValidator("[0-9]{5}"));
		
		final Label communeLabel = new Label("commune", 
				new PropertyModel<String>(serviceModel, "commune"));
		communeLabel.setOutputMarkupId(true);

		final ModalWindow codePostalPicker = buildCodePostalPicker();
		codePostalPicker.setContent(new SelectCodePostalPanel2(codePostalPicker.getContentId(), serviceModel) {
			private static final long serialVersionUID = 1L;

			@Override
			public void onSave(AjaxRequestTarget target) {
				target.addComponent(codePostalTextField);
				target.addComponent(communeLabel);
				codePostalPicker.close(target);
			}

			@Override
			public void onCancel(AjaxRequestTarget target) {
				codePostalPicker.close(target);
			}
		});

		// Gestion du picker de service parent
		final RequiredTextField<String> parentCodeUOTextField = new RequiredTextField<String>("parentCodeUO", 
				new PropertyModel<String>(serviceModel, "parent.codeUO"));
		parentCodeUOTextField.setOutputMarkupId(true);
		
		final ModalWindow parentCodeUOPicker = buildParentCodeUOPicker();
		parentCodeUOPicker.setContent(new SelectParentPanel1(parentCodeUOPicker.getContentId(), serviceModel) {
			private static final long serialVersionUID = 1L;

			@Override
			public void onSave(AjaxRequestTarget target) {
				target.addComponent(parentCodeUOTextField);
				parentCodeUOPicker.close(target);
			}
			
			@Override
			public void onCancel(AjaxRequestTarget target) {
				parentCodeUOPicker.close(target);
			}
		});

        // newForm
        ServiceNewForm newForm = new ServiceNewForm("newForm", new CompoundPropertyModel<OrgUnit>(serviceModel), codePostalPicker, parentCodeUOPicker) {
			private static final long serialVersionUID = 1L;

			/* (non-Javadoc)
			 * @see org.apache.wicket.markup.html.form.Form#onSubmit()
			 */
			@Override
			protected void onSubmit() {
				try {
					codePostalTextField.validate();
					
					OrgUnit service = getModelObject();
					
					// Appel e la couche de service
					User user = userManager.getByMatricule(matricule);
					taskManager.assignNewService(service, user);
					
					// Affiche le message sur la page redirigee
					getSession().info("La création du service a été prise en compte et a été soumise à l'approbation du référent de direction.");
					setResponsePage(ServicesListPage.class);
				} catch (ConstraintViolationException e) {
					error("La demande de création de service n'a pas été prise en compte.");
					Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
					for (ConstraintViolation<?> constraintViolation : violations) {
						error(constraintViolation.getMessage());
					}
					setResponsePage(ServiceNewPage.this);
				} catch (BusinessException be) {
					error(be.getMessage());
					setResponsePage(ServiceNewPage.this);
				}
			}
        };
        add(newForm);

        newForm.add(parentCodeUOPicker);
        newForm.add(codePostalPicker);
        
		newForm.add(codePostalTextField);
		newForm.add(communeLabel);

		parentCodeUOTextField.setEnabled(false);
		newForm.add(parentCodeUOTextField);

		newForm.add(new Button("btnSubmit"));
		
		Button btnCancel = new Button("btnCancel") {
			private static final long serialVersionUID = 1L;
			@Override
			public void onSubmit() {
				// Affiche le message sur la page redirigee
        		getSession().warn("Aucune création de service n'a été effectuée.");
				setResponsePage(ServicesListPage.class);
			}
		};
		// Pas de validation
		btnCancel.setDefaultFormProcessing(false);
		newForm.add(btnCancel);

	}
	
	/**
	 * @return
	 */
	private ModalWindow buildCodePostalPicker() {
		final ModalWindow codePostalPicker = new ModalWindow("codePostalPicker");
//		codePostalPicker.setTitle("Choisir un code postal");
		codePostalPicker.setInitialWidth(800);
		codePostalPicker.setWidthUnit("px");
		codePostalPicker.setUseInitialHeight(true);
//		codePostalPicker.setInitialHeight(480);
		codePostalPicker.setHeightUnit("px");
		codePostalPicker.setResizable(true);
		codePostalPicker.setMaskType(MaskType.TRANSPARENT);
		return codePostalPicker;
	}

	/**
	 * @return
	 */
	private ModalWindow buildParentCodeUOPicker() {
		final ModalWindow parentCodeUOPicker = new ModalWindow("parentCodeUOPicker");
//		parentCodeUOPicker("Choisir un code postal");
		parentCodeUOPicker.setInitialWidth(800);
		parentCodeUOPicker.setWidthUnit("px");
		parentCodeUOPicker.setUseInitialHeight(true);
//		parentCodeUOPicker.setInitialHeight(480);
		parentCodeUOPicker.setHeightUnit("px");
		parentCodeUOPicker.setResizable(true);
		parentCodeUOPicker.setMaskType(MaskType.TRANSPARENT);
		return parentCodeUOPicker;
	}

}

